package org.hbhk.hms.mq.tx.mq;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.hbhk.hms.mq.tx.provider.DefaultMessageSender;
import org.hbhk.hms.mq.tx.provider.MqMessageProvider;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;

import net.bytebuddy.ByteBuddy;

public class ProducerFactoryBean<T> implements FactoryBean<MqMessageProvider<T>>, DisposableBean {

	private Class<? extends MqMessageProvider<T>> producerClass;

	private DefaultMessageSender<T> instance = null;

	public ProducerFactoryBean(Class<? extends MqMessageProvider<T>> producerClass) {
		super();
		this.producerClass = producerClass;
	}

	@Override
	public void destroy() throws Exception {
		this.destroy();
	}

	@Override
	public Class<?> getObjectType() {
		return producerClass;
	}

	@Override
	public boolean isSingleton() {
		return true;
	}

	@Override
	public DefaultMessageSender<T> getObject() throws Exception {
		instance = (DefaultMessageSender) getImpClass().newInstance();
		return instance;
	}

	private Map<Class<? extends MqMessageProvider<T>>, Class<?>> implMap = new ConcurrentHashMap<>();

	private synchronized Class<?> getImpClass() {
		if (!implMap.containsKey(producerClass)) {
			Class<? extends DefaultMessageSender> implClazz = new ByteBuddy().subclass(DefaultMessageSender.class)
					.implement(producerClass).make().load(producerClass.getClassLoader()).getLoaded();
			implMap.putIfAbsent(producerClass, implClazz);
		}
		return implMap.get(producerClass);
	}

}
